﻿using System;
using System.Collections.Specialized;
using System.Windows.Controls;
using Notoric.Gui.Windows;

namespace Notoric.Gui.Commands
{
    /// <summary>
    /// Implements a command for changing the time signature.
    /// </summary>
    public class ChangeTimeSignatureCommand : RibbonCommand
    {
        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ChangeTimeSignatureCommand"/> class.
        /// </summary>
        /// <param name="mainWindow">
        /// <para>
        /// Type: <see cref="MainWindow"/>
        /// </para>
        /// <para>
        /// The main application window.
        /// </para>
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// The <paramref name="mainWindow"/> is <see langword="null"/>.
        /// </exception>
        public ChangeTimeSignatureCommand(MainWindow mainWindow)
            : base(mainWindow)
        {
            ScreenTipTitle = "Change Time Signature";
            ScreenTipText = "Changes the time signature of the selected part of the current composition.";

            mainWindow.DocumentPane.SelectionChanged += new SelectionChangedEventHandler(DocumentPane_SelectionChanged);
        }

        #endregion
        
        #region ICommand Members

        /// <inheritdoc/>
        public override bool CanExecute(object parameter)
        {
            return 
                (
                    ApplicationWindow.ActivePage != null && ApplicationWindow.ActivePage.SelectedContent == ViewModel.Elements.SelectedContentType.Music && 
                    ApplicationWindow.ActivePage.SelectedSections.Count == 1
                ) ||
                    ApplicationWindow.DocumentPane.SelectedItem is LinearCompositionViewPanel;
        }

        /// <inheritdoc/>
        public override void Execute(object parameter)
        {
            ViewModel.Elements.Composition composition;

            if (ApplicationWindow.ActivePage != null)
                composition = ((ViewModel.Elements.MusicSection)ApplicationWindow.ActivePage.SelectedSections[0]).PresentedComposition;
            else
                composition = ((ViewModel.Elements.LinearCompositionView)((LinearCompositionViewPanel)ApplicationWindow.DocumentPane.SelectedItem).DataContext).Content.PresentedComposition;

            var dlg = new ChangeTimeSignatureDialog()
            {
                DataContext = composition
            };
            dlg.ShowDialog();
        }

        #endregion

        #region Event Handlers

        /// <summary>
        /// Handles the SelectionChanged event of the DocumentPane control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="SelectionChangedEventArgs"/> instance containing the event data.</param>
        private void DocumentPane_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (activePage != null)
                activePage.SelectedSections.CollectionChanged -= SelectedSections_CollectionChanged;

            activePage = ApplicationWindow.ActivePage;

            if (activePage != null)
                activePage.SelectedSections.CollectionChanged += new NotifyCollectionChangedEventHandler(SelectedSections_CollectionChanged);

            RaiseCanExecuteChanged();
        }

        /// <summary>
        /// Handles the CollectionChanged event of the SelectedSections control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Collections.Specialized.NotifyCollectionChangedEventArgs"/> instance containing the event data.</param>
        void SelectedSections_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            RaiseCanExecuteChanged();
        }

        #endregion

        #region Private Fields

        /// <summary>
        /// Holds the currently active page.
        /// </summary>
        private ViewModel.Elements.Page activePage;

        #endregion
    }
}
